package com.epower.tools;

import cn.hutool.core.date.DateUtil;
import com.epower.tools.bean.AnalogChannelInfo;
import com.epower.tools.bean.StatusChannelInfo;
import org.apache.log4j.Logger;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * @description: Comtrade Cfg文件解析
 * @author: LIU JUN
 * @create: 2021-03-17 15:24
 */
public class CfgFile {
    static Logger logger = Logger.getLogger(CfgFile.class);

    private List<String> lines = new ArrayList<>();
    private String stationName;
    private String deviceName;
    private String stdYear;
    private String totalChannels;
    private String analogChannels;
    private String statusChannels;

    private List<String> allPntNames;
    private List<AnalogChannelInfo> analogChannelInfoList;
    private List<StatusChannelInfo> statusChannelInfoList;
    private String freq;
    private String nrates;
    private String samp;
    private String endsamp;
    private String firstTimeText;
    private String triggerTimeText;
    private String fileType;
    private String timemult;

    private byte[] content;


    public CfgFile(byte[] content) {
        this.content = content;
        this.analogChannelInfoList = new ArrayList<>();
        this.statusChannelInfoList = new ArrayList<>();
        this.allPntNames = new ArrayList<>();
    }
    /**
     * 读取文件
     *
     * @param filePath
     * @throws Exception
     */
    public void loadFile(byte[] content) throws Exception {
        String res = new java.lang.String(content, "gbk");
        String[] arrayStr = res.split("\\r?\\n");
        lines = Arrays.asList(arrayStr);
//        lines = FileUtil.readLines(filePath, GBK);
    }

    public void reload() throws Exception {
        loadFile(this.content);
    }

    /**
     * 开始解析
     *
     * @throws Exception
     */
    public void parse() throws Exception {
        this.reload();
        if (lines == null || lines.isEmpty()) {
            throw new Exception("文件内容为空");
        }
        this.parseBaseInfo();
        this.parseChanelAndType();
        this.parseAnaChannelInfo();
        this.parseStatusChannelInfo();
        this.parseFreqAndSample();

        for (AnalogChannelInfo analogChannelInfo : this.analogChannelInfoList) {
            allPntNames.add(analogChannelInfo.getChId());
        }

        for (StatusChannelInfo statusChannelInfo : this.statusChannelInfoList) {
            allPntNames.add(statusChannelInfo.getChId());
        }
    }

    private void parseBaseInfo() {
        String[] arr = lines.get(0).split(",");
        this.stationName = arr[0];
        this.deviceName = arr[1];
        this.stdYear = arr[2];
    }

    private void parseChanelAndType() {
        String[] arr = lines.get(1).split(",");
        this.totalChannels = arr[0];
        this.analogChannels = arr[1].replace("A", "");
        this.statusChannels = arr[2].replace("D", "");
    }

    private boolean isAnaLine(String line) {
        if (line == null || line.isEmpty()) {
            return false;
        }
        if (line.toLowerCase().endsWith("s") || line.toLowerCase().endsWith("p")) {
            return true;
        }
        return false;
    }

    private boolean isStatusLine(String line) {
        if (line == null || line.isEmpty()) {
            return false;
        }
        if (line.endsWith("0") || line.endsWith("1")) {
            return true;
        }
        return false;
    }

    private void parseAnaChannelInfo() {
        for (String line : this.lines) {
            if (!isAnaLine(line)) {
                continue;
            }
            try {
                this.analogChannelInfoList.add(AnalogChannelInfo.newInstance(line));
            } catch (Exception e) {
                continue;
            }
        }
    }

    private void parseStatusChannelInfo() {
        for (String line : this.lines) {
            if (!isStatusLine(line)) {
                continue;
            }
            try {
                this.statusChannelInfoList.add(StatusChannelInfo.newInstance(line));
            } catch (Exception e) {
                continue;
            }
        }
    }

    private void parseFreqAndSample() {
        Integer nextLineNo = 2 + this.analogChannelInfoList.size() + this.statusChannelInfoList.size();
        this.freq = this.lines.get(nextLineNo++);
        this.nrates = this.lines.get(nextLineNo++);
        String[] sp = this.lines.get(nextLineNo++).split(",");
        this.samp = sp[0];
        this.endsamp = sp[1];

        this.firstTimeText = this.lines.get(nextLineNo++);
        this.triggerTimeText = this.lines.get(nextLineNo++);
        this.fileType = this.lines.get(nextLineNo++);
        this.timemult = this.lines.get(nextLineNo);
    }

    @Override
    public String toString() {
        return "ComtradeCfg{" +
                ", \nstationName='" + stationName + '\'' +
                ", \ndeviceName='" + deviceName + '\'' +
                ", \nstdYear='" + stdYear + '\'' +
                ", \ntotalChannels='" + totalChannels + '\'' +
                ", \nanalogChannels='" + analogChannels + '\'' +
                ", \nstatusChannels='" + statusChannels + '\'' +
                ", \nanalogChannelInfoList=" + analogChannelInfoList +
                ", \nstatusChannelInfoList=" + statusChannelInfoList +
                ", \nfreq='" + freq + '\'' +
                ", \nnrates='" + nrates + '\'' +
                ", \nsamp='" + samp + '\'' +
                ", \nendsamp='" + endsamp + '\'' +
                ", \nfirstTimeText='" + firstTimeText + '\'' +
                ", \ntriggerTimeText='" + triggerTimeText + '\'' +
                ", \nfileType='" + fileType + '\'' +
                ", \ntimemult='" + timemult + '\'' +
                '}';
    }


    /**
     * 终端的描述
     */
    public String getStationName() {
        return stationName;
    }

    /**
     * 采样速率
     *
     * @return
     */
    public Long getSampRateValue() {
        return Long.parseLong(this.samp);
    }

    /**
     * 总点数
     *
     * @return
     */
    public Long totalPntCount() {
        return Long.parseLong(this.endsamp);
    }

    /**
     * 时间标记乘数系数
     *
     * @return
     */
    public Double getTimemultDouble() {
        return Double.parseDouble(timemult);
    }

    /**
     * 查找通道采样值的占位
     *
     * @param chId
     * @return
     */
    public Integer findValPosition(String chId) {
        AtomicInteger index = new AtomicInteger(-1);
        allPntNames.stream()
                //指定匹配逻辑
                .filter(s -> {
                    //每比对一个元素，数值加1
                    index.getAndIncrement();
                    return s.startsWith(chId);
                }).findFirst();
        int i = this.allPntNames.indexOf(chId);
        return index.get();
//        return this.allPntNames. indexOf(chId);
    }

    public List<String> getAllPntNames() {
        return allPntNames;
    }

    public String getDeviceName() {
        return deviceName;
    }

    public String getStdYear() {
        return stdYear;
    }

    public String getTotalChannels() {
        return totalChannels;
    }

    public String getAnalogChannels() {
        return analogChannels;
    }

    public String getStatusChannels() {
        return statusChannels;
    }

    public List<AnalogChannelInfo> getAnalogChannelInfoList() {
        return analogChannelInfoList;
    }

    public List<StatusChannelInfo> getStatusChannelInfoList() {
        return statusChannelInfoList;
    }

    public String getFreq() {
        return freq;
    }

    public String getNrates() {
        return nrates;
    }


    public String getFirstTimeText() {
        return firstTimeText;
    }

    public String getTriggerTimeText() {
        return triggerTimeText;
    }

    public String getFileType() {
        return fileType;
    }


    final String stdTimeFormat = "dd-MM-yyyy HH:mm:ss";

    public long toMicroSeconds(String timeText) {
        timeText = timeText.replace("/", "-").replace(",", " ");
        String tmp = timeText.substring(0, stdTimeFormat.length());
        long microSeconds = DateUtil.parse(tmp, stdTimeFormat).getTime() * 1000;
        microSeconds += Long.valueOf(timeText.substring(stdTimeFormat.length() + 1));
        return microSeconds;
    }

}
